package com.ancun.controller;

import com.ancun.dao.GirlRepository;
import com.ancun.entity.Girl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping(value = "girls")
public class GirlController
{
    private final static Logger logger = LoggerFactory.getLogger(GirlController.class);

    @Autowired
    private GirlRepository girlReository;

    @RequestMapping(value = "add")
    public Girl girlAdd(@RequestParam("name") String name,
                        @RequestParam("age") Integer age,
                        @RequestParam("id") int id) {
        Girl girl = new Girl();
        girl.setName(name);
        girl.setAge(age);
        girl.setId(id);
        return girlReository.save(girl);
    }

    @RequestMapping(value="delete")
    public String delete(int id)
    {
        girlReository.delete(id);
        return "Success to delete.";
    }

    @RequestMapping(value="q1")
    public Girl query1(int id)
    {
        return girlReository.findOne(id);
    }

    @RequestMapping(value="q2")
    public List<Girl> query2(int age)
    {
        return girlReository.findByAge(age);
    }

    @RequestMapping(value = "all")
    public List<Girl> query3() {
        return girlReository.findAll();
    }

    @RequestMapping(value="count")
    public long cout()
    {
        return girlReository.count();
    }

    @RequestMapping(value="exist")
    public boolean exist(int id)
    {
        return girlReository.exists(id);
    }

    @RequestMapping(value="modify")
    int modifyAgeAndNameById(int age, String name, int id)
    {
        return girlReository.modifyAgeAndNameById(age, name, id);
    }

    @RequestMapping(value="q4")
    List<Girl> queryByName(String name)
    {
        return girlReository.findByName(name);
    }

    /**
     * 查询所有的分页查询
     * @param page
     * @param size
     * @param sort
     * @return
     */
    @RequestMapping(value = "findall", method=RequestMethod.GET)
    public Page<Girl> getEntryByPageable(@RequestParam(value = "page", defaultValue = "0")int page,
                                         @RequestParam(value = "size", defaultValue = "20") int size,
                                         @RequestParam(value = "sort", defaultValue = "id") String sort)
    {
        return girlReository.findAll(new PageRequest(page, size, new Sort(Sort.Direction.ASC, sort)));
    }

    /**
     * 带条件的分页查询
     * @param name
     * @param age
     * @param page
     * @param size
     * @param sort
     * @return
     */
    @RequestMapping(value = "findallpage")
    public Page<Girl> findAllByLikeNameEqualAge(final String name,
                                        final int age,
                                        @RequestParam(value = "page", defaultValue = "0") int page,
                                        @RequestParam(value = "size", defaultValue = "20") int size,
                                        @RequestParam(value = "sort", defaultValue = "id") String sort)
    {
        // 使用list构建
        Specification<Girl> specification = new Specification<Girl>() {
            @Override
            public Predicate toPredicate(Root<Girl> root,
                                         CriteriaQuery<?> query,
                                         CriteriaBuilder cb) {

                // list添加所有条件
                List<Predicate> list = new ArrayList<Predicate>();
                list.add(cb.equal(root.get("age").as(Long.class), age));                  // equal
                list.add(cb.like(root.get("name").as(String.class), "%" + name + "%"));     // like

                Predicate[] p = new Predicate[list.size()];

                // and条件
                query.where(cb.and(list.toArray(p)));

                // 排序
                query.orderBy(cb.desc(root.get("id")), cb.desc(root.get("age")));

                return query.getRestriction();
            }
        };

        // 这里分页排序的话上面query orderBy就失效了
        return girlReository.findAll(specification, new PageRequest(page, size, new Sort(Sort.Direction.ASC, sort)));
    }

    // 按名称的分页
    @RequestMapping(value = "findbyname")
    public Page<Girl> findByName(final String name,
                                 @RequestParam(value = "page", defaultValue = "0") int page,
                                 @RequestParam(value = "size", defaultValue = "20") int size,
                                 @RequestParam(value = "sort", defaultValue = "id") String sort)
    {
        return girlReository.findByName(name, new PageRequest(page, size, new Sort(Sort.Direction.ASC, sort)));
    }

    // HQL的分页查询
    @RequestMapping(value = "findbyage")
    public Page<Girl> findByAge(final int age,
                                 @RequestParam(value = "page", defaultValue = "0") int page,
                                 @RequestParam(value = "size", defaultValue = "20") int size,
                                 @RequestParam(value = "sort", defaultValue = "id") String sort)
    {
        Page<Girl> pageGirl = girlReository.findByAge(age, new PageRequest(page, size, new Sort(Sort.Direction.ASC, sort)));
        List<Girl> content = pageGirl.getContent();
        for(Girl girl: content) {
            logger.info(girl.getId() + " " + girl.getName() + " " + girl.getAge());
        }
        return pageGirl;
    }
}


